package org.ccay.async.processor;

import org.ccay.async.AsyncMessage;
import org.ccay.async.ContextAwareMessage;
import org.ccay.async.IMessageProcessor;
import org.ccay.core.exception.ApplicationException;
import org.ccay.core.log.CcayLoggerFactory;
import org.ccay.core.log.ILogger;
import org.ccay.core.request.IRequestContext;
import org.ccay.core.request.impl.RequestContext;
import org.ccay.core.request.impl.RequestContextManager;


/**
 * 具有上下文绑定能力的消息处理器。
 * 	
 * 
 * @since Feb 20, 2012
 */
public class ContextAwareProcessor implements IMessageProcessor {
	
	private static final ILogger logger = CcayLoggerFactory.getLogger(ContextAwareProcessor.class);
	
	/** 原始的Processor **/
	private IMessageProcessor processor;
 
	/**
	 * @param processor
	 */
	public ContextAwareProcessor(IMessageProcessor processor) {
		this.processor = processor;
	}

	/* (non-Javadoc)
	 * @see org.ccay.async.IMessageProcessor#process(org.ccay.async.AsyncMessage)
	 */
	public void process(AsyncMessage message) throws ApplicationException {
		logger.debug("Begin to process async message.");
		if(message instanceof ContextAwareMessage) {
			// 从消息中获取上下文相关的信息
			IRequestContext ctx = message.getContext(IRequestContext.class);
			if (ctx == null) {
				// 调用原始的消息处理器进行消息的处理
				logger.debug("Begin to process async message without request context.");
				this.processor.process(((ContextAwareMessage)message).getOriginalMessage());
				logger.debug("Process async message sucessfully and without request context.");
				return;
			}
			//添加是否需要跳过安全检查标识
			((RequestContext)ctx).setSkipSecurityCheck(true);
			// 将IRequestContext绑定到当前线程
			logger.debug("Set current request context before process message.");
			RequestContextManager.setCurrent(ctx);
			try{
				// 调用原始的消息处理器进行消息的处理
				logger.debug("Begin to process async message with request context.");
				this.processor.process(((ContextAwareMessage)message).getOriginalMessage());
				logger.debug("Process async message sucessfully and with request context.");
			}finally{
				// 销毁当前线程所绑定的IRequestContext
				RequestContextManager.removeCurrent();
			}
		} else {
			logger.debug("Begin to process async message in ContextAwareProcessor.");
			this.processor.process(message);
			logger.debug("Process async message sucessfully in ContextAwareProcessor.");
		}
	}
}
